// Proxy 对引用对象的代理
// Reflect 实现都对象的基本操作(一定要对代理本身作修改才能触发，而不是对象本身)
// proxy 13个方法 参数都一样
// reflect 13个方法，参数都一样  帮助我们直接操纵对象

// const personProxy = new Proxy(person,{
//     get(target,key,receiver){

//     },
//     set(target,key,receiver){

//     },
//     //拦截函数调用
//     apply(){    

//     },
//     // 拦截in操作符
//     has(){

//     },
//     //拦截forin 
//     ownKeys(){

//     },
//     // 拦截new操作符
//     construct(){

//     },
//     // 拦截删除的操作delete
//     deleteProperty(){

//     }

// })


const person = {
    name: 'wyx',
    age: 22
}
// let personProxy = new Proxy(person, {
//     get(target, key, receiver) {
//         if (target.age <= 18) {
//             return Reflect.get(target, key, receiver)
//         } else {
//             return '成年啦！'
//         }
//     }
// })
// console.log(personProxy.name)

// console.log(person.name)
// console.log(Reflect.get(person,'name',person))

// 观察者模式
const set:Set<Function> = new Set()
function autoRun(fn: Function) {
    if (!set.has(fn)) {
        set.add(fn)
    }
}
const observable = <T extends object>(params: T) => {
    return new Proxy(params, {
        set(target, key, value, receiver) {
            const res = Reflect.set(target, key, value, receiver)
            set.forEach(fn => fn())
            return res
        }
    })
}


const personProxy = observable(person)
autoRun(()=>console.log('变化了！'))
// 代理修改要放在最后面，否则触发的时候set里还没回调
personProxy.age = 19
